package com.gateway.loadBalance;

import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import org.apache.commons.collections.CollectionUtils;

import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.IntStream;

/**
 * @author Huangkai
 */
public abstract class AbstractLoadBalance {

    /**
     * 服务列表和权限
     */
    protected List<Invoker> invokerList;

    protected final Multiset<Invoker> results = HashMultiset.create();

    public AbstractLoadBalance(List<Invoker> invokerList) {
        this.invokerList = invokerList;
    }

    public Invoker selectHost(){
        List<Invoker> list = getInvokers();
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        if (list.size() == 1) {
            return list.get(0);
        }
        return doSelect();
    }

    public Invoker selectHost(Object client){
        List<Invoker> list = getInvokers();
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        if (list.size() == 1) {
            return list.get(0);
        }
        return doSelect(client);
    }

    protected Invoker doSelect(){
        return null;
    }

    protected Invoker doSelect(Object client){
        return null;
    }

    protected boolean addInvoker(Invoker invoker){
        if (getInvokers() != null){
            return invokerList.add(invoker);
        }
        return false;
    }

    protected boolean removeInvoker(Invoker invoker){
        if (getInvokers() != null){
            return invokerList.remove(invoker);
        }
        return false;
    }

    protected List<Invoker> getInvokers(){
        return invokerList;
    }

    public void result(int loop) {
        results.clear();
        if (loop < 1) {
            throw new IllegalArgumentException();
        }
        IntStream.range(0, loop).forEach(i -> results.add(selectHost()));
        Set<Multiset.Entry<Invoker>> entrySet = results.entrySet();
        entrySet.stream().sorted(Comparator.comparingInt(Multiset.Entry::getCount)).forEach(System.out::println);
    }
}
